home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
icon tools
/
iconian
/
sources
/
popup.e
< prev
next >
Wrap
Text File
|
1996-04-07
|
30KB
|
1,119 lines
/*
* PopUpButton Gadget Class
*
* Copyright ©1995 by Chad Randall mbissaymssiK Software
* All Rights Reserved.
*
* This source is released for instructional purposes ONLY.
* This source is not to be modified or altered in any way.
*
* If you would like me to add a feature, or remove a bug,
* PLEASE contact me at:
*
* crandall@msen.com
* -or-
* 229 S.Washington St, Manchester, Michigan 48158-9680 USA
*/
-> Best viewed with a TAB size of 2
/* Programming notes
*
* Remember, in libraries, E will not allow [2,x,3,y,5,z]:LONG... so, we always
* need to build taglists/structs in memory. I haven't found an easy way to do this
* so far... so I have a "base" list in memory, alloc space, then copy it over, and
* finally longptr[n]:=x the variable parts. Is there an easier way?
*/
OPT PREPROCESS
LIBRARY 'popup.gadget',3,0,'popupgadget 1.0 (19.9.95)' IS
initPopUpClass,
freePopUpClass,
addObjectToList,
disposeObjects,
disposeObjectNodes,
buildPalette,
disposePalette,
addTextToList
/*
# define bigger(x,y) (IF x>y THEN x ELSE y)
# define smaller(x,y) (IF x<y THEN x ELSE y)
# define limit(x,y,z) (IF x<y THEN y ELSE (IF x<z THEN x ELSE z))
*/
MODULE 'diskfont'
MODULE 'devices/inputevent'
MODULE 'exec/memory','exec/lists','exec/nodes'
MODULE 'graphics','graphics/text','graphics/gfx','graphics/rastport'
MODULE 'intuition/cghooks','intuition/classes','intuition/classusr','intuition/gadgetclass',
'intuition/icclass','intuition/imageclass','intuition/intuition','intuition/screens'
MODULE 'utility','utility/tagitem'
MODULE 'amigalib/boopsi'
->MODULE 'mod/boopsi'
MODULE 'amigalib/lists'
MODULE 'tools/installhook'
MODULE 'gadgets/popup'
MODULE 'mod/compare'
->MODULE 'mod/libdebug'
OBJECT puinst
window:PTR TO window -> Window that is opened when gadget is active.
objlist:PTR TO lh -> Points to a exec-linked list of "objects"
numobjs:LONG -> Number of objects displayed...no bigger than across*down
active:LONG -> Currently active object.
lastactive:LONG -> Unused, really...
original:LONG -> Last active one, incase of an abort.
frameobj:PTR TO image -> Class allocated frame obj to display bevel boxes.
gridw:LONG
gridh:LONG -> Size of individual boxes. All boxes must be the same size.
across:LONG
down:LONG -> Number of objects across and down.
lastsent:LONG
winx:INT
winy:INT
winw:INT
winh:INT
gadgetbordertype:INT
windowbordertype:INT
arrow:INT -> Specifies that the user wants a "popup arrow" drawn.
imagespacing:INT
windowspacing:INT
autosize:INT
layout:INT
centerimages:INT
centergadgetimage:INT
ENDOBJECT
PROC dispatchPopUpGad(cl:PTR TO iclass, o, msg:PTR TO msg)
/*
* This is the main routine, coming from input.device (mainly),
* E needs A4 setup to a global area, but installhook takes care of
* that for us.
*/
DEF retval=FALSE
DEF switch
IF (utilitybase=0) THEN utilitybase:=OpenLibrary('utility.library',36)
switch:=msg.methodid
SELECT switch
CASE OM_NEW;retval:=pu_new(cl,o,msg)
CASE OM_DISPOSE;retval:=pu_dispose(cl,o,msg)
CASE OM_SET;retval:=pu_set(cl, o, msg)
CASE OM_UPDATE;retval:=pu_set(cl,o,msg)
CASE OM_GET;retval:=pu_get(cl, o, msg)
-> CASE OM_NOTIFY;retval:=pu_notify(cl,o,msg)
CASE GM_RENDER;retval:=pu_render(cl, o, msg)
CASE GM_GOACTIVE;retval:=pu_goactive(cl,o,msg)
CASE GM_HANDLEINPUT;retval:=pu_handleinput(cl,o,msg)
CASE GM_GOINACTIVE;retval:=pu_goinactive(cl,o,msg)
DEFAULT;retval:=doSuperMethodA(cl, o, msg)
ENDSELECT
ENDPROC retval
PROC pu_goinactive(cl:PTR TO iclass,o:PTR TO object,gpgi:PTR TO gpgoinactive)
DEF g:PTR TO gadget
DEF inst:PTR TO puinst
DEF retval
retval:=doSuperMethodA(cl,o,gpgi)
g:=o
g.flags:=g.flags AND Not(GFLG_SELECTED)
inst:=INST_DATA(cl, o)
IF inst.window -> If we have a window opened, close it.
CloseWindow(inst.window)
inst.window:=0
ENDIF
notifyactive(cl, o, 0, gpgi.ginfo,TRUE) -> Signal the window we are dying, and our last active was...
pu_render(cl, o, gpgi) -> Rerender our unselected imagery.
ENDPROC retval
PROC pu_handleinput(cl:PTR TO iclass,o:PTR TO object,gpi:PTR TO gpinput)
DEF g:PTR TO gadget
DEF switch,ie:PTR TO inputevent
DEF retval=GMR_MEACTIVE
DEF inst:PTR TO puinst
DEF ie_switch
g:=o
inst:=INST_DATA(cl, o)
ie:=gpi.ievent
WHILE ((ie) AND (retval=GMR_MEACTIVE))
ie_switch:=ie.class
SELECT ie_switch
CASE IECLASS_RAWMOUSE
switch:=ie.code
IF (switch=SELECTDOWN) THEN switch:=MENUDOWN -> Handles when we are "Activated"
IF (switch=MENUUP) THEN switch:=SELECTUP
SELECT switch
CASE SELECTUP
checkmouse(gpi,inst,g)
notifyactive(cl, o, 0, gpi.ginfo)
IF (gpi.mousex < 0) OR (gpi.mousex > g.width) OR (gpi.mousey < 0) OR (gpi.mousey > g.height)
retval:=GMR_NOREUSE OR GMR_VERIFY
ELSE
retval:=GMR_NOREUSE
ENDIF
CASE MENUDOWN
changeactive(inst,gpi.ginfo.drinfo,inst.original)
notifyactive(cl, o, 0, gpi.ginfo)
retval:=GMR_REUSE
DEFAULT
checkmouse(gpi,inst,g)
ENDSELECT
CASE IECLASS_TIMER
IF (inst.window)
checkmouse(gpi,inst,g)
IF ((g.activation AND GACT_RELVERIFY)=0) THEN notifyactive(cl, o, OPUF_INTERIM, gpi.ginfo)
ENDIF
ENDSELECT
ie:=ie.nextevent
ENDWHILE
ENDPROC retval
PROC checkmouse(gpi:PTR TO gpinput,inst:PTR TO puinst,g:PTR TO gadget)
DEF winx,winy,over,a,b
IF ((inst.window) AND (gpi.ginfo.window))
winx:=gpi.ginfo.window.leftedge-inst.winx+g.leftedge-inst.window.leftedge+gpi.mousex
winy:=gpi.ginfo.window.topedge-inst.winy+g.topedge-inst.window.topedge+gpi.mousey
IF ((winx<0) OR (winx>=inst.winw) OR (winy<0) OR (winy>=inst.winh))
changeactive(inst,gpi.ginfo.drinfo,inst.original)
ELSE
a:=(winx/inst.gridw)
b:=(winy/inst.gridh)
over:=a+(b*inst.across)
changeactive(inst,gpi.ginfo.drinfo,over)
ENDIF
ENDIF
ENDPROC
PROC changeactive(inst:PTR TO puinst,drawinfo,new)
IF (inst.active<>new)
IF ((new>=0) AND (new<=inst.numobjs))
inst.lastactive:=inst.active
inst.active:=new
updatewindow(inst,drawinfo,inst.active,inst.lastactive)
ENDIF
ENDIF
ENDPROC
PROC pu_get(cl:PTR TO iclass,o:PTR TO object,opg:PTR TO opget)
DEF retval
DEF inst:PTR TO puinst
DEF switch
DEF longptr:PTR TO LONG
inst:=INST_DATA(cl,o)
switch:=opg.attrid
longptr:=opg.storage
SELECT switch
CASE PUA_ACTIVE
longptr[0]:=inst.active
retval:=TRUE
CASE PUA_NUMBEROFOBJECTS
longptr[0]:=inst.numobjs+1
retval:=TRUE
CASE PUA_ROWS
longptr[0]:=inst.down
retval:=TRUE
CASE PUA_COLUMNS
longptr[0]:=inst.across
retval:=TRUE
DEFAULT
retval:=doSuperMethodA(cl,o,opg)
ENDSELECT
ENDPROC retval
PROC pu_new(cl:PTR TO iclass,o:PTR TO object,ops:PTR TO opset)
DEF inst:PTR TO puinst
DEF object:PTR TO object
IF (object:=doSuperMethodA(cl, o, ops))
inst:=INST_DATA(cl, object)
inst.objlist:=GetTagData(PUA_OBJECTS,0,ops.attrlist)
inst.active:=GetTagData(PUA_ACTIVE,0,ops.attrlist)
inst.arrow:=GetTagData(PUA_POPUPARROW,PUARROW_NONE,ops.attrlist)
inst.across:=bigger(GetTagData(PUA_COLUMNS,1,ops.attrlist),1)
inst.down:=bigger(GetTagData(PUA_ROWS,1,ops.attrlist),1)
inst.gadgetbordertype:=GetTagData(PUA_GADGETBORDER,-1,ops.attrlist)
inst.windowbordertype:=GetTagData(PUA_WINDOWBORDER,-1,ops.attrlist)
inst.windowspacing:=GetTagData(PUA_WINDOWSPACING,FALSE,ops.attrlist)
inst.imagespacing:=GetTagData(PUA_IMAGESPACING,FALSE,ops.attrlist)
inst.autosize:=GetTagData(PUA_AUTOGADGETRESIZE,FALSE,ops.attrlist)
inst.layout:=GetTagData(PUA_AUTOWINDOWLAYOUT,FALSE,ops.attrlist)
inst.centerimages:=GetTagData(PUA_CENTERIMAGES,TRUE,ops.attrlist)
inst.centergadgetimage:=GetTagData(PUA_CENTERGADGETIMAGE,TRUE,ops.attrlist)
inst.frameobj:=NewObjectA(NIL,'frameiclass',[IA_RECESSED,FALSE,IA_EDGESONLY,FALSE,TAG_END])
/* The above is legal in an E-built library, because it is STATIC. */
IF ((inst.objlist) AND (inst.frameobj))
layouteverything(object,inst)
ELSE
coerceMethodA(cl,o,[OM_DISPOSE,0,TAG_END]:LONG)
object:=NIL
ENDIF
ENDIF
ENDPROC object
PROC layouteverything(g:PTR TO gadget,inst:PTR TO puinst)
DEF node:PTR TO imagenode,next
DEF i=0
DEF w,h,gw,gh
DEF longptr:PTR TO LONG
DEF im:PTR TO image
inst.numobjs:=0
inst.gridw:=0
inst.gridh:=0
node:=inst.objlist.head
REPEAT
next:=node.listnode.succ
IF (next)
IF (node.object)
w,h:=maxsize(node.object.width,node.object.height,node.frametype)
IF (inst.imagespacing)
w:=w+4
h:=h+4
ENDIF
inst.gridw:=bigger(w,inst.gridw)
inst.gridh:=bigger(h,inst.gridh)
ENDIF
IF (node.selobject)
w,h:=maxsize(node.selobject.width,node.selobject.height,node.selframetype)
IF (inst.imagespacing)
w:=w+4
h:=h+4
ENDIF
inst.gridw:=bigger(w,inst.gridw)
inst.gridh:=bigger(h,inst.gridh)
ENDIF
inst.numobjs:=inst.numobjs+1
ENDIF
node:=next
UNTIL (next=0)
inst.numobjs:=inst.numobjs-1
->->-> inst.numobjs:=smaller(i-1,((inst.across*inst.down)-1))
node:=inst.objlist.head
REPEAT
next:=node.listnode.succ
IF (next)
IF (inst.centerimages)
IF (node.object)
node.private_offsetx:=(inst.gridw-node.object.width)/2
node.private_offsety:=(inst.gridh-node.object.height)/2
ENDIF
IF (node.selobject)
node.private_sel_offsetx:=((inst.gridw-node.selobject.width)/2)
node.private_sel_offsety:=((inst.gridh-node.selobject.height)/2)
ENDIF
ELSE
w:=0
h:=0
gw:=0
gh:=0
IF (node.frametype>=0) THEN w,h:=maxsize(0,0,node.frametype)
IF (node.selobject)
IF (node.selframetype>=0) THEN gw,gh:=maxsize(0,0,node.selframetype)
ENDIF
node.private_offsetx:=w/2
node.private_offsety:=h/2
node.private_sel_offsetx:=gw/2
node.private_sel_offsety:=gh/2
ENDIF
ENDIF
node:=next
UNTIL (next=0)
gw:=0
gh:=0
IF (inst.autosize)
IF (g.gadgetrender<>0)
im:=g.gadgetrender
gw:=im.width
gh:=im.height
IF (g.selectrender<>0)
im:=g.selectrender
gw:=bigger(gw,im.width)
gh:=bigger(gh,im.height)
ENDIF
ELSE
gw:=inst.gridw
gh:=inst.gridh
ENDIF
IF (inst.gadgetbordertype>=0)
gw,gh:=maxsize(gw,gh,inst.gadgetbordertype)
ENDIF
IF (inst.arrow=PUARROW_POPUP)
gw:=gw+16
ENDIF
longptr:=New(64)
longptr[0]:=GA_WIDTH
longptr[1]:=gw
longptr[2]:=GA_HEIGHT
longptr[3]:=gh
longptr[4]:=TAG_END
SetAttrsA(g,longptr)
Dispose(longptr)
ENDIF
ENDPROC
PROC pu_dispose(cl:PTR TO iclass,o:PTR TO object,msg:PTR TO msg)
DEF inst:PTR TO puinst
inst:=INST_DATA(cl,o)
IF inst.window
CloseWindow(inst.window)
inst.window:=0
ENDIF
IF inst.frameobj
DisposeObject(inst.frameobj)
inst.frameobj:=0
ENDIF
RETURN doSuperMethodA(cl,o,msg)
ENDPROC
PROC pu_set(cl:PTR TO iclass,o:PTR TO object,ops:PTR TO opset)
DEF inst:PTR TO puinst
DEF rp,tag:PTR TO tagitem
DEF retval
DEF gpr:PTR TO gprender
DEF newimagestate=0
DEF opu:PTR TO opupdate
DEF opn:PTR TO opnotify
DEF longptr:PTR TO LONG
DEF original
DEF newlayout=FALSE,ox,oy,ow,oh
inst:=INST_DATA(cl, o)
ox:=o::gadget.leftedge
oy:=o::gadget.topedge
ow:=o::gadget.width
oh:=o::gadget.height
original:=inst.active
retval:=doSuperMethodA(cl, o, ops)
IF (ops.attrlist)
IF (tag:=FindTagItem(GA_DISABLED,ops.attrlist)) THEN newimagestate:=TRUE
IF (tag:=FindTagItem(GA_IMAGE,ops.attrlist))
newimagestate:=TRUE
newlayout:=TRUE
ENDIF
IF (tag:=FindTagItem(GA_SELECTRENDER,ops.attrlist))
newimagestate:=TRUE
newlayout:=TRUE
ENDIF
IF (tag:=FindTagItem(PUA_ACTIVE,ops.attrlist))
inst.active:=limit(tag.data,0,inst.numobjs)
IF (inst.active<>original) THEN newimagestate:=TRUE
ENDIF
IF (tag:=FindTagItem(PUA_ROWS,ops.attrlist))
inst.down:=tag.data
ENDIF
IF (tag:=FindTagItem(PUA_COLUMNS,ops.attrlist))
inst.across:=tag.data
ENDIF
IF (tag:=FindTagItem(PUA_AUTOGADGETRESIZE,ops.attrlist))
inst.autosize:=tag.data
ENDIF
IF (tag:=FindTagItem(PUA_WINDOWSPACING,ops.attrlist))
inst.windowspacing:=tag.data
ENDIF
IF (tag:=FindTagItem(PUA_IMAGESPACING,ops.attrlist))
inst.imagespacing:=tag.data
newlayout:=TRUE
ENDIF
IF (tag:=FindTagItem(PUA_WINDOWBORDER,ops.attrlist))
inst.windowbordertype:=tag.data
ENDIF
IF (tag:=FindTagItem(PUA_GADGETBORDER,ops.attrlist))
inst.gadgetbordertype:=tag.data
newlayout:=TRUE
newimagestate:=TRUE
ENDIF
IF (tag:=FindTagItem(PUA_CENTERGADGETIMAGE,ops.attrlist))
inst.centergadgetimage:=tag.data
newimagestate:=TRUE
newlayout:=TRUE
ENDIF
IF (tag:=FindTagItem(PUA_POPUPARROW,ops.attrlist))
inst.arrow:=tag.data
newlayout:=TRUE
newimagestate:=TRUE
ENDIF
IF (tag:=FindTagItem(PUA_CENTERIMAGES,ops.attrlist))
inst.centerimages:=tag.data
newlayout:=TRUE
newimagestate:=TRUE
ENDIF
IF (newlayout) THEN layouteverything(o,inst)
IF ((ox<>o::gadget.leftedge) OR (oy<>o::gadget.topedge) OR (ow<>o::gadget.width) OR (oh<>o::gadget.height))
rp:=ObtainGIRPort(ops.ginfo)
IF (rp)
EraseRect(rp,ox,oy,ox+ow-1,oy+oh-1)
ReleaseGIRPort(rp)
ENDIF
newimagestate:=TRUE
ENDIF
IF (newimagestate)
-> IF (IF (ops.methodid=OM_UPDATE) THEN (IF (ops::opupdate.flags<>OPUF_INTERIM) THEN TRUE ELSE FALSE) ELSE TRUE)
retval:=1 -> Notify app a visual change will take place.
rp:=ObtainGIRPort(ops.ginfo)
IF (rp)
NEW gpr
gpr.methodid:=GM_RENDER
gpr.ginfo:=ops.ginfo
gpr.rport:=rp
gpr.redraw:=GREDRAW_UPDATE
doMethodA(o,gpr)
ReleaseGIRPort(rp)
END gpr
ENDIF
-> ENDIF
opn:=New(64)
longptr:=New(64)
longptr[0]:=TAG_END
opn.methodid:=OM_NOTIFY
opn.attrlist:=longptr
opn.ginfo:=ops.ginfo
opn.flags:=0
doMethodA(o,opn)
Dispose(opn)
Dispose(longptr)
-> notifyactive(cl, o, 0, ops.ginfo)
ENDIF
ENDIF
ENDPROC retval
/*
PROC pu_notify(cl:PTR TO iclass, o:PTR TO object, opu:PTR TO opupdate)
DEF retval
DEF longptr:PTR TO LONG
DEF inst:PTR TO puinst
DEF opn:PTR TO opnotify
inst:=INST_DATA(cl,o)
longptr:=New(64)
longptr[0]:=GA_ID
longptr[1]:=o::gadget.gadgetid
longptr[2]:=PUA_ACTIVE
longptr[3]:=inst.active
IF (opu.attrlist=NIL)
longptr[4]:=TAG_END
ELSE
longptr[4]:=TAG_MORE
longptr[5]:=opu.attrlist
ENDIF
opn:=New(64)
opn.methodid:=OM_NOTIFY
opn.attrlist:=longptr
opn.ginfo:=opu.ginfo
opn.flags:=opu.flags
opn.flags:=0
retval:=doSuperMethodA(cl,o,opn)
Dispose(opn)
Dispose(longptr)
ENDPROC retval
*/
PROC pu_goactive(cl:PTR TO iclass, o:PTR TO object, gpi:PTR TO gpinput)
DEF retval=GMR_MEACTIVE
DEF rp:PTR TO rastport
DEF inst:PTR TO puinst
DEF gi:PTR TO gadgetinfo
DEF g:PTR TO gadget
DEF left,top,midx,midy
DEF width,height
DEF gprender:PTR TO gprender
DEF longptr:PTR TO LONG
g:=o
gi:=gpi.ginfo
inst:=INST_DATA(cl, g)
IF (g.flags AND GFLG_DISABLED) THEN RETURN GMR_NOREUSE
doSuperMethodA(cl,o,gpi)
-> IF (gpi.ievent)
g.flags:=g.flags OR GFLG_SELECTED
IF (rp:=ObtainGIRPort(gi))
NEW gprender
gprender.methodid:=GM_RENDER
gprender.ginfo:=gi
gprender.rport:=rp
gprender.redraw:=GREDRAW_UPDATE
doMethodA(o,gprender)
END gprender
ReleaseGIRPort(rp)
IF ((inst.window=0) AND (gi.window))
inst.winw:=(inst.across*inst.gridw)
inst.winh:=(inst.down*inst.gridh)
width,height:=maxsize(inst.winw,inst.winh,inst.windowbordertype)
IF (inst.windowspacing)
width:=width+4
height:=height+4
ENDIF
inst.winx:=((width-inst.winw)/2)
inst.winy:=((height-inst.winh)/2)
midx:=gpi.mousex-((g.width/2)+(IF (inst.arrow=PUARROW_POPUP) THEN 8 ELSE 0))
midy:=gpi.mousey-(g.height/2)
left:=(((gi.window.leftedge+g.leftedge+(g.width/2))-((inst.active - ((inst.active/inst.across)*inst.across)) * inst.gridw) - (inst.gridw/2))-inst.winx) +(IF (inst.arrow=PUARROW_POPUP) THEN 8 ELSE 0)+midx
top:=((gi.window.topedge+g.topedge+(g.height/2))-((inst.active/inst.across)*inst.gridh) - (inst.gridh/2))-inst.winy+midy
longptr:=New(240)
CopyMem({deftags},longptr,90)
longptr[1]:=left
longptr[3]:=top
longptr[5]:=width
longptr[7]:=height
longptr[9]:=gi.screen
inst.window:=OpenWindowTagList(0,longptr) -> We cannot use [tags]:LONG because this is a library!
Dispose(longptr)
inst.lastactive:=-1
inst.original:=inst.active
updatewindow(inst,gpi.ginfo.drinfo,-1,-1)
IF (inst.windowbordertype>=0)
IF inst.window
longptr:=New(64)
CopyMem({frametaglist},longptr,64)
longptr[1]:=width
longptr[3]:=height
longptr[5]:=FALSE
longptr[7]:=inst.windowbordertype
SetAttrsA(inst.frameobj,longptr)
Dispose(longptr)
DrawImageState(inst.window.rport,inst.frameobj,0,0,IDS_NORMAL,gpi.ginfo.drinfo)
ENDIF
ENDIF
ENDIF
retval:=GMR_MEACTIVE
ENDIF
-> ELSE
-> retval:=GMR_NOREUSE
-> ENDIF
ENDPROC retval
PROC updatewindow(inst:PTR TO puinst,drawinfo:PTR TO drawinfo,updatethisone,andthisone)
DEF xx,yy
DEF node:PTR TO imagenode
DEF next
DEF cur
IF inst.window=0 THEN RETURN
node:=inst.objlist.head
FOR yy:=0 TO (inst.down-1)
FOR xx:=0 TO (inst.across-1)
next:=node.listnode.succ
IF (next)
cur:=(yy*inst.across)+xx
node.private_lastdrawn:=IF (inst.active=cur) THEN TRUE ELSE FALSE
IF ((updatethisone=-1) OR (updatethisone=cur) OR (andthisone=cur))
drawnode(inst.window.rport,inst.winx+(xx*inst.gridw),inst.winy+(yy*inst.gridh),inst.gridw,inst.gridh,node,inst,drawinfo,node.private_lastdrawn)
ENDIF
node:=next
ENDIF
ENDFOR
ENDFOR
inst.lastactive:=inst.active
ENDPROC
PROC drawnode(rast,x,y,w,h,node:PTR TO imagenode,inst:PTR TO puinst,drawinfo:PTR TO drawinfo,sel)
DEF obj,ids=IDS_NORMAL,offx,offy
DEF longptr:PTR TO LONG,frame
IF (node)
SetAPen(rast,drawinfo.pens[IF sel THEN node.selfillcolor ELSE BACKGROUNDPEN])
RectFill(rast,x,y,(x+w-1),(y+h-1))
obj:=node.object
offx:=node.private_offsetx
offy:=node.private_offsety
frame:=node.frametype
IF (sel)
frame:=node.selframetype
IF node.selobject
obj:=node.selobject
offx:=node.private_sel_offsetx
offy:=node.private_sel_offsety
ELSE
ids:=IDS_SELECTED
ENDIF
ENDIF
IF (frame>=0)
longptr:=New(64)
CopyMem({frametaglist},longptr,64)
longptr[1]:=w
longptr[3]:=h
longptr[5]:=IF (sel) THEN TRUE ELSE FALSE
longptr[7]:=frame
SetAttrsA(inst.frameobj,longptr)
Dispose(longptr)
DrawImageState(rast,inst.frameobj,x,y,IDS_NORMAL,drawinfo)
ENDIF
DrawImageState(rast,obj,x+offx,y+offy,ids,drawinfo)
ENDIF
ENDPROC
frametaglist:
LONG IA_WIDTH,0,
IA_HEIGHT,0,
IA_RECESSED,0,
IA_FRAMETYPE,0,
IA_EDGESONLY,TRUE,
IA_BGPEN,0,
IA_FGPEN,0,
TAG_END
PROC maxsize(bw,bh,frametype)
-> Used to be: PROC maxsize(inst:PTR TO puinst,o1:PTR TO image,frametype,drawinfo)
-> DEF framebox:PTR TO impframebox
-> DEF fbox:PTR TO ibox
-> DEF cbox:PTR TO ibox
DEF aw=0,ah=0
SELECT frametype
CASE FRAME_DEFAULT;aw:=2;ah:=2
CASE FRAME_BUTTON;aw:=4;ah:=2
CASE FRAME_RIDGE;aw:=8;ah:=4
CASE FRAME_ICONDROPBOX;aw:=12;ah:=6
ENDSELECT
bw:=bw+aw
bh:=bh+ah
/*
* Unfortunatly, frameiclass always seems to return +4,+4 for it's dimensions
* after giving it IM_FRAMEBOX... so, I'm deactivating this code until I discover
* why... I've tried ALOT of different things... no luck
-> IF drawinfo=0 THEN drawinfo:=inst.drawinfo ...PUA_DRAWINFO no longer...
IF drawinfo=0 THEN RETURN o1.width+16,o1.height+16
SetAttrsA(inst.frameobj,[IA_FRAMETYPE,frametype,IA_DOUBLEEMBOSS,TRUE,TAG_END])
framebox:=New(64)
cbox:=New(32)
fbox:=New(32)
cbox.width:=o1.width
cbox.height:=o1.height
cbox.left:=0
cbox.top:=0
framebox.methodid:=IM_FRAMEBOX
framebox.contentsbox:=cbox
framebox.framebox:=fbox
framebox.drinfo:=drawinfo
framebox.frameflags:=0
doMethodA(inst.frameobj,framebox)
w:=bigger(o1.width,fbox.width)
h:=bigger(o1.height,fbox.height)
Dispose(framebox)
Dispose(cbox)
Dispose(fbox)
*/
ENDPROC bw,bh
PROC notifyactive(cl:PTR TO iclass, o:PTR TO gadget, flags, ginfo,flag=FALSE)
DEF msg:PTR TO opnotify
DEF inst:PTR TO puinst
DEF longptr:PTR TO LONG
inst:=INST_DATA(cl, o)
IF ((inst.active<>inst.lastsent) OR (flag=TRUE))
NEW msg
longptr:=New(40)
longptr[0]:=PUA_ACTIVE
longptr[1]:=inst.active
longptr[2]:=GA_ID
longptr[3]:=o.gadgetid
longptr[4]:=TAG_END
msg.methodid:=OM_NOTIFY
msg.attrlist:=longptr
msg.ginfo:=ginfo
msg.flags:=flags
doSuperMethodA(cl,o, msg)
END msg
Dispose(longptr)
ENDIF
inst.lastsent:=inst.active
ENDPROC
-> Erase and rerender the gadget.
PROC pu_render(cl:PTR TO iclass, o:PTR TO object, gpr:PTR TO gprender)
DEF inst:PTR TO puinst, rp, retval=TRUE, pens:PTR TO INT
DEF g:PTR TO gadget
DEF node:PTR TO imagenode
DEF i
DEF issel
DEF shine,shadow
DEF xx,yy
DEF ox=0,oy=0
DEF longptr:PTR TO LONG,switch
DEF im:PTR TO image
DEF im2:PTR TO image
g:=o
inst:=INST_DATA(cl, g)
retval:=doSuperMethodA(cl,o,gpr)
pens:=gpr.ginfo.drinfo.pens
IF gpr.methodid=GM_RENDER
rp:=gpr.rport
ELSE
rp:=ObtainGIRPort(gpr.ginfo)
ENDIF
IF (rp)
node:=inst.objlist.head
IF (inst.active>0)
FOR i:=0 TO inst.active-1
IF (node) THEN node:=node.listnode.succ
ENDFOR
ENDIF
IF (node.listnode.succ)
issel:=(g.flags AND GFLG_SELECTED)
xx:=IF (inst.arrow=PUARROW_POPUP) THEN 8 ELSE 0
IF (inst.gadgetbordertype>=0)
longptr:=New(64)
CopyMem({frametaglist},longptr,64)
longptr[1]:=g.width
longptr[3]:=g.height
longptr[5]:=IF (issel) THEN TRUE ELSE FALSE
longptr[7]:=inst.gadgetbordertype
longptr[9]:=FALSE
SetAttrsA(inst.frameobj,longptr)
Dispose(longptr)
DrawImageState(rp,inst.frameobj,g.leftedge,g.topedge,IDS_NORMAL,gpr.ginfo.drinfo)
ox,oy:=maxsize(0,0,inst.gadgetbordertype)
ox:=ox/2
oy:=oy/2
ELSE
SetAPen(rp,pens[BACKGROUNDPEN])
SetDrMd(rp,RP_JAM2)
RectFill(rp,g.leftedge,g.topedge,g.leftedge+g.width,g.topedge+g.height)
ENDIF
im:=g.gadgetrender
IF ((issel) AND (g.selectrender<>0)) THEN im:=g.selectrender
IF (inst.centergadgetimage=FALSE) THEN ox:=ox+(xx*2)
IF (im)
IF (inst.centergadgetimage)
ox:=((g.width-im.width)/2)+xx
oy:=((g.height-im.height)/2)
ENDIF
DrawImageState(rp,im,g.leftedge+ox,g.topedge+oy,IF (issel) THEN IDS_SELECTED ELSE IDS_NORMAL,gpr.ginfo.drinfo)
ELSE
IF (inst.centergadgetimage)
ox:=((g.width-inst.gridw)/2)+xx
oy:=((g.height-inst.gridh)/2)
ENDIF
drawnode(rp,g.leftedge+ox,g.topedge+oy,inst.gridw,inst.gridh,node,inst,gpr.ginfo.drinfo,issel)
ENDIF
IF (inst.arrow)
IF (issel)
shine:=pens[SHADOWPEN]
shadow:=pens[SHINEPEN]
ELSE
shine:=pens[SHINEPEN]
shadow:=pens[SHADOWPEN]
ENDIF
switch:=inst.arrow
xx,yy:=maxsize(0,0,inst.gadgetbordertype)
SELECT switch
CASE PUARROW_POPUP
ox:=g.leftedge+(xx/2)
oy:=g.topedge+(yy/2)
SetAPen(rp,shadow)
Move(rp,ox+13,oy+1)
Draw(rp,ox+13,oy+(g.height-yy-2))
SetAPen(rp,shine)
Move(rp,ox+14,oy+1)
Draw(rp,ox+14,oy+(g.height-yy-2))
xx:=ox+2
yy:=g.topedge+(g.height/2)-4
FOR ox:=xx TO xx+6 STEP 3
FOR oy:=yy TO yy+6 STEP 3
SetAPen(rp,shadow)
WritePixel(rp,ox,oy)
WritePixel(rp,ox+1,oy)
WritePixel(rp,ox,oy+1)
SetAPen(rp,shine)
WritePixel(rp,ox+2,oy+1)
WritePixel(rp,ox+2,oy+2)
WritePixel(rp,ox+1,oy+2)
ENDFOR
ENDFOR
CASE PUARROW_TINY
xx:=g.leftedge+g.width-6-(xx/2)
yy:=g.topedge+1+(yy/2)
SetAPen(rp,shadow)
Move(rp,xx+1,yy)
Draw(rp,xx+1,yy+6)
Move(rp,xx+2,yy+6)
Draw(rp,xx+5,yy+3)
SetAPen(rp,shine)
Move(rp,xx,yy)
Draw(rp,xx,yy+6)
Move(rp,xx+2,yy+5)
Draw(rp,xx+2,yy)
Draw(rp,xx+5,yy+3)
SetAPen(rp,pens[BACKGROUNDPEN])
Move(rp,xx+3,yy+2)
Draw(rp,xx+3,yy+4)
Draw(rp,xx+4,yy+3)
ENDSELECT
ENDIF
ENDIF
IF (g.flags AND GFLG_DISABLED)
SetAPen(rp,pens[TEXTPEN])
SetDrMd(rp,RP_JAM1)
setafpt(rp,[%10001000100010000010001000100010],1)
RectFill(rp,g.leftedge,g.topedge,g.leftedge+g.width-1,g.topedge+g.height-1)
ENDIF
IF (gpr.methodid<>GM_RENDER) THEN ReleaseGIRPort(rp)
ELSE
retval:=FALSE
ENDIF
ENDPROC retval
PROC setafpt(rast:PTR TO rastport,pattern,size)
rast.areaptrn:=pattern
rast.areaptsz:=size
ENDPROC
deftags:
LONG WA_LEFT,0,
WA_TOP,0,
WA_WIDTH,0,
WA_HEIGHT,0,
WA_CUSTOMSCREEN,0,
WA_BORDERLESS,TRUE,
WA_RMBTRAP,TRUE,
WA_AUTOADJUST,TRUE,
WA_ACTIVATE,FALSE,
WA_NOCAREREFRESH,TRUE,
WA_SIMPLEREFRESH,TRUE,
-> WA_SMARTREFRESH,TRUE,
TAG_END,0
CHAR 0, '$VER: popup.gadget 1.0 (11.9.95)', 0,0
PROC freePopUpClass(cl)
FreeClass(cl)
IF utilitybase
CloseLibrary(utilitybase)
utilitybase:=0
ENDIF
ENDPROC
PROC initPopUpClass()
DEF cl:PTR TO iclass
utilitybase:=OpenLibrary('utility.library',36)
-> IF cl:=MakeClass(NIL, 'buttongclass', NIL, SIZEOF puinst, 0)
IF cl:=MakeClass(NIL, 'gadgetclass', NIL, SIZEOF puinst, 0)
installhook(cl.dispatcher, {dispatchPopUpGad})
ENDIF
ENDPROC cl
PROC addObjectToList(list,object,frametype,selobject,selframetype,selfillcolor)
DEF node:PTR TO imagenode
node:=AllocMem(SIZEOF imagenode,MEMF_ANY OR MEMF_CLEAR)
node.object:=object
node.frametype:=frametype
node.selobject:=selobject
node.selfillcolor:=selfillcolor
node.selframetype:=selframetype
node.private_iallocated:=-4
AddTail(list,node)
ENDPROC node
PROC addTextToList(list,text,textattr:PTR TO textattr,drawinfo:PTR TO drawinfo) HANDLE
DEF rast:PTR TO rastport
DEF xor=0,w=0,h=0
DEF textextent:PTR TO textextent
DEF it1:PTR TO intuitext
DEF it2:PTR TO intuitext
DEF slen,textstring=0
DEF obj1,obj2
DEF longptr:PTR TO LONG
DEF node:PTR TO imagenode
DEF mytextattr=0:PTR TO textattr
DEF textfont=0:PTR TO textfont
mytextattr:=AllocMem(SIZEOF textattr,MEMF_ANY OR MEMF_CLEAR)
IF (textattr)
mytextattr.name:=String(StrLen(textattr.name))
StrCopy(mytextattr.name,textattr.name)
mytextattr.ysize:=textattr.ysize
mytextattr.style:=textattr.style
mytextattr.flags:=textattr.flags
ELSE
mytextattr.name:='topaz.font'
mytextattr.ysize:=8
ENDIF
diskfontbase:=OpenLibrary('diskfont.library',36)
IF (diskfontbase)
textfont:=OpenDiskFont(mytextattr)
CloseLibrary(diskfontbase)
ELSE
textfont:=OpenFont(mytextattr)
ENDIF
IF (textfont)
NEW rast,textextent
slen:=StrLen(text)
InitRastPort(rast)
xor:=xor OR (IF ((textfont.style AND 1)<>(textattr.style AND 1)) THEN 1 ELSE 0)
xor:=xor OR (IF ((textfont.style AND 2)<>(textattr.style AND 2)) THEN 2 ELSE 0)
xor:=xor OR (IF ((textfont.style AND 4)<>(textattr.style AND 4)) THEN 4 ELSE 0)
SetFont(rast,textfont)
SetSoftStyle(rast,xor,7)
TextExtent(rast,text,slen,textextent)
w:=Abs(textextent.extent.minx)+Abs(textextent.extent.maxx)+1
h:=Abs(textextent.extent.miny)+Abs(textextent.extent.maxy)+1
END rast,textextent
it1:=AllocMem(SIZEOF intuitext,MEMF_ANY OR MEMF_CLEAR)
it2:=AllocMem(SIZEOF intuitext,MEMF_ANY OR MEMF_CLEAR)
textstring:=String(StrLen(text))
StrCopy(textstring,text,ALL)
it1.itext:=textstring
it2.itext:=textstring
it1.frontpen:=6
it1.backpen:=14
it1.drawmode:=RP_JAM1
it2.drawmode:=RP_JAM1
it1.itextfont:=mytextattr
it2.itextfont:=mytextattr
longptr:=New(128)
CopyMem({itexttags},longptr,128)
longptr[1]:=w
longptr[3]:=h
longptr[5]:=it1
longptr[7]:=drawinfo.pens[TEXTPEN]
obj1:=NewObjectA(NIL,{itexticlass},longptr)
longptr[5]:=it2
longptr[7]:=drawinfo.pens[FILLTEXTPEN]
obj2:=NewObjectA(NIL,{itexticlass},longptr)
Dispose(longptr)
IF ((obj1) AND (obj2))
node:=addObjectToList(list,obj1,-1,obj2,FRAME_BUTTON,FILLPEN)
node.private_iallocated:=-5
node.private_itextn:=it1
node.private_itexts:=it2
node.private_textfont:=textfont
node.private_textattr:=mytextattr
node.private_text:=textstring
ELSE
CloseFont(textfont)
ENDIF
ELSE
Raise(-1)
ENDIF
EXCEPT
IF (mytextattr.name) THEN DisposeLink(mytextattr.name)
IF (textstring) THEN DisposeLink(textstring)
IF (mytextattr) THEN FreeMem(mytextattr,SIZEOF textattr)
IF (textfont) THEN CloseFont(textfont)
ENDPROC node
itexttags:
LONG IA_WIDTH,0,
IA_HEIGHT,0,
IA_DATA,0,
IA_FGPEN,0,
TAG_END
PROC disposeObjectNodes(list:PTR TO lh)
DEF node:PTR TO imagenode,next
node:=list.head
REPEAT
next:=node.listnode.succ
IF (next)
IF (node.private_iallocated<-3)
Remove(node)
FreeMem(node,SIZEOF imagenode)
ENDIF
ENDIF
node:=next
UNTIL (next=0)
ENDPROC
PROC disposeObjects(list:PTR TO lh)
DEF node:PTR TO imagenode,next
node:=list.head
REPEAT
next:=node.listnode.succ
IF (next)
IF node.private_iallocated=-5 -> A ITEXTICLASS we allocated, so we dispose the IA_DATA field.
IF (node.private_text) THEN DisposeLink(node.private_text)
IF (node.private_textfont) THEN CloseFont(node.private_textfont)
IF (node.private_textattr) THEN FreeMem(node.private_textattr,SIZEOF textattr)
IF (node.private_itextn) THEN FreeMem(node.private_itextn,SIZEOF intuitext)
IF (node.private_itexts) THEN FreeMem(node.private_itexts,SIZEOF intuitext)
ENDIF
IF node.object THEN DisposeObject(node.object)
IF node.selobject THEN DisposeObject(node.selobject)
ENDIF
node:=next
UNTIL (next=0)
ENDPROC
PROC buildPalette(firstcolor,lastcolor,width,height)
DEF i,obj1,obj2
DEF list:PTR TO mlh
DEF pal1tags
DEF pal2tags
list:=AllocMem(SIZEOF mlh,MEMF_ANY OR MEMF_CLEAR)
newList(list)
pal1tags:=New(64)
pal2tags:=New(64)
CopyMem({pal1taglist},pal1tags,60)
CopyMem({pal2taglist},pal2tags,60)
PutLong(pal1tags+4,width)
PutLong(pal1tags+12,height)
PutLong(pal2tags+4,width)
PutLong(pal2tags+12,height)
FOR i:=firstcolor TO lastcolor
PutLong(pal1tags+20,i)
PutLong(pal2tags+20,i)
obj1:=NewObjectA(NIL,{fillrectclass},pal1tags)
obj2:=NewObjectA(NIL,{fillrectclass},pal2tags)
IF obj1
IF obj2
addObjectToList(list,obj1,-1,obj2,1,BACKGROUNDPEN)
ENDIF
ENDIF
ENDFOR
Dispose(pal1tags)
Dispose(pal2tags)
ENDPROC list
pal1taglist:
LONG IA_WIDTH,0,
IA_HEIGHT,0,
IA_FGPEN,0,
IA_MODE,RP_JAM2,
TAG_END
pal2taglist:
LONG IA_WIDTH,0,
IA_HEIGHT,0,
IA_FGPEN,0,
IA_MODE,RP_JAM2,
TAG_END
PROC disposePalette(list)
disposeObjects(list)
disposeObjectNodes(list)
FreeMem(list,SIZEOF mlh)
ENDPROC
PROC main() IS EMPTY
itexticlass:
CHAR 'itexticlass',0
fillrectclass:
CHAR 'fillrectclass',0